#include "miniGoogle.h"
#include "cargadorDeArchivos.h"
#include <cmath>
#define TOTAL_PARTICIONES 174000

//pre: tiene que existir el archivo de apariciones de la palabra
int miniGooglear(string palabra, diccionario_t* diccionario, diccionarioPorIndice_t* dicPorIndice){

	//if(palabraApareceEnDiccionario(palabra, dicPorIndice)){
	if(diccionario->mapa.find(palabra) != diccionario->mapa.end()){
		if(diccionario->mapa.at(palabra).bitSetDeFragmentos != nullptr){
			return diccionario->mapa.at(palabra).bitSetDeFragmentos->count();
		}else{
			return 0;
		}
	}else{
		return 0;
	}

}

int miniGooglear(string palabra1, string palabra2, diccionario_t* dic, diccionarioPorIndice_t* dicPorIndice){
	termino_t termino1;
	//if(palabraApareceEnDiccionario(palabra1, dicPorIndice)){
	if(dic->mapa.find(palabra1) != dic->mapa.end()){
		termino1 = dic->mapa.at(palabra1);
	} else { return 0; }
	termino_t termino2;
	//if(palabraApareceEnDiccionario(palabra2, dicPorIndice)){
	if(dic->mapa.find(palabra2) != dic->mapa.end()){
		termino2 = dic->mapa.at(palabra2);
	} else { return 0; }

	if (termino1.bitSetDeFragmentos != nullptr && termino2.bitSetDeFragmentos != nullptr){
		return ( *(termino1.bitSetDeFragmentos) & *(termino2.bitSetDeFragmentos) ).count();
	}else { return 0; }
}

float miniGoogleDistanciaEntrePalabras(string palabra1, string palabra2, diccionario_t* dic, diccionarioPorIndice_t* dicPorIndice){
	float maximo, minimo, interseccion;
	maximo = miniGooglear(palabra1, dic, dicPorIndice);
	minimo = miniGooglear(palabra2, dic, dicPorIndice);
	interseccion = miniGooglear(palabra1, palabra2, dic, dicPorIndice);
	if(maximo < minimo){
		float auxi = maximo;
		maximo = minimo;
		minimo = auxi;
	}
	float log2 = log(2);
	maximo = log(maximo) / log2;
	minimo = log(minimo) / log2;
	interseccion = log(interseccion) / log2;
	float logN = log(TOTAL_PARTICIONES) / log2;
	if(logN == minimo) return 1;
	float distancia = ( maximo - interseccion ) / ( logN - minimo );
	return distancia;
}

/*float miniGoogleDistanciaPalabraFrase(string palabra, string frase, diccionario_t* dic, diccionarioPorIndice_t* dicPorIndice){
	float acumulador = 0;
	//Esto se mueve afuera del for de miniGoogle
	//vector<string> listaDePalabras;
	//split(frase, ' ', &listaDePalabras);
	size_t cantidadDePalabras = listaDePalabras.size();
	for(auto& palabraDeFrase : listaDePalabras)
		acumulador += miniGoogleDistanciaEntrePalabras(palabra, palabraDeFrase, dic, dicPorIndice);
	listaDePalabras.clear();
	return acumulador / cantidadDePalabras;
}
*/

float miniGoogleDistanciaPalabraFrase(string palabra, vector<string>* listaDePalabras, diccionario_t* dic, diccionarioPorIndice_t* dicPorIndice){
	float acumulador = 0;
	size_t cantidadDePalabras = listaDePalabras->size();
	for(auto& palabraDeFrase : *listaDePalabras){
		acumulador += miniGoogleDistanciaEntrePalabras(palabra, palabraDeFrase, dic, dicPorIndice);
	}
	return (acumulador / cantidadDePalabras);
}
